<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/9 0009
 * Time: 下午 4:27
 */
namespace app\admin\controller;

use app\common\service\MiniProgramHelp;
use app\common\BaseHelper;
use app\lib\wechat\WXBizMsgCrypt;
use think\Cache;
use think\Controller;
use app\admin\model\Tenant;
use app\admin\model\Miniprogramtemplate;

/**
 * 微信
 * @package backend\controllers
 */
class Wx extends Controller {


    public function index($appId){
        if (empty($appId)) {
            self::saveMiniProgramEventLog('', '', 'appid为空');
            exit('success');
        }

        //接收微信推送xml数据
        $xmlData = file_get_contents("php://input");
        $xmlData = simplexml_load_string($xmlData, 'SimpleXMLElement', LIBXML_NOCDATA);

        $decryptMsg = self::decryptMsg($xmlData);
        self::saveMiniProgramEventLog($appId, $decryptMsg, ' 解密后的数据');

        //自动化测试的专用测试小程序的信息如下：
        if ($appId == 'wxd101a85aa106f53e') {
            $queryAuthCode = trim(str_replace('QUERY_AUTH_CODE:', '', $decryptMsg['decryptMsg']->Content));
            $apiQueryAuth = self::_wechatComponentApiQueryAuth($queryAuthCode);
            self::_wechatSendMsg((string)$decryptMsg['decryptMsg']->FromUserName, $apiQueryAuth['authorization_info']['authorizer_access_token'], $queryAuthCode);

            exit('success');
        }

        //微信授权小程序信息Y

        $businessMiniProgram = Tenant::get(['appId'=>$appId]);
        if (empty($businessMiniProgram)) {
            self::saveMiniProgramEventLog($appId, $xmlData, ' 数据库没有找到数据');
            exit('success');
        }

        if (!empty($decryptMsg['decryptMsg'])) {
            switch ($decryptMsg['decryptMsg']->Event) {
                //审核成功
                case 'weapp_audit_success':
                    $businessMiniProgram->wxStatus = 4;
                    $businessMiniProgram->save();
                    self::saveMiniProgramEventLog($appId, $decryptMsg, '审核成功');

                    //小程序权限配置
                    //BusinessMiniProgram::openAuthcode($businessMiniProgram->businessId, $businessMiniProgram->templateId);

                    //发布代码
                    MiniProgramHelp::releaseCode($businessMiniProgram->id);
                    break;
                //审核失败
                case 'weapp_audit_fail':
                    $businessMiniProgram->wxStatus = 3;
                    $businessMiniProgram->auditMsg = $decryptMsg['decryptMsg']->Reason;
                    $businessMiniProgram->save();
                    self::saveMiniProgramEventLog($appId, $decryptMsg, '审核失败');
                    break;
                //未知事件
                default:
                    self::saveMiniProgramEventLog($appId, $decryptMsg, ' GET請求数据：' . json_encode($_GET) . '   错误事件类型:' . $decryptMsg['decryptMsg']->Event);
                    break;
            }
        } else {
            self::saveMiniProgramEventLog($appId, $xmlData, ' GET請求数据：' . json_encode($_GET) . ' 数据解密失败');
        }


        echo 'success';

    }
    /**
     * 授权事件接收
     * @author fei <xliang.fei@gmail.com>
     */
    public function Ticket()
    {
        $xmlData = file_get_contents("php://input");
        $xmlData = simplexml_load_string($xmlData, 'SimpleXMLElement', LIBXML_NOCDATA);

        $decryptMsg = self::decryptMsg($xmlData);
        file_put_contents('2.txt',json_encode($decryptMsg));
        if ($decryptMsg['errCode'] == 0) {
            //$authorizerAppid = (string)$decryptMsg['decryptMsg']->AuthorizerAppid;
            //if ($authorizerAppid != 'wxd101a85aa106f53e') {
            // 设置缓存数据
            $path = APP_PATH . 'ticket/cache/MiaoDaoOpenVerifyTicket.php';
            file_put_contents($path,(string)$decryptMsg['decryptMsg']->ComponentVerifyTicket);


            //}
        }

        self::saveMiniProgramTicketLog($xmlData, $decryptMsg, '授权事件接收(生成Ticket)');

        echo 'success';
    }

    /**
     * 微信授权回调
     * @author fei <xliang.fei@gmail.com>
     */
    public function AuthcodeCallback(){

        $businessId = session('TENANT_ID');

        $data = ['code' => 'success', 'msg' => '恭喜，授权成功！'];

        if (empty($businessId)) {
            return ['code' => 'error', 'msg' => '错误！'];
        }

        //授权码
        $authCode = request()->get('auth_code');
        //过期时间
        $expiresTime = time() + 55 * 60 * 2;
        //接口调用凭据
        $result = MiniProgramHelp::getApiQueryAuth($authCode);

        if (empty($result['authorization_info'])) {
            return ['code' => 'error', 'msg' => '错误！'];
        }

        //判断权限是否有
        if (!empty($result['authorization_info']['func_info'])) {
            $isFunc = false;
            foreach ($result['authorization_info']['func_info'] as $value) {
                if ($value['funcscope_category']['id'] == 18) {
                    $isFunc = true;
                }
            }

            if (!$isFunc) {
                $data = ['code' => 'error', 'msg' => '未授权【开发管理与数据分析权限】，无法完成授权！'];
            }
        }

        //http://s.1miaodao.cn/applet/authcode-callback?b=c7b52162-3856-11e7-8b20-96da850cac3b&auth_code=queryauthcode@@@dv5FDgvFjAnktVeIECJeYUxkynA5sgy9pIl7JdynNnzItzsND8vcBlbNMx9Y-DxwljOE46iUnPnxzCi9Xo1y-Q&expires_in=3600

        //判断该appid是否已经绑定过

//        $isAppid = BusinessMiniProgram::find()
//            ->where(['authorizerAppid' => $result['authorization_info']['authorizer_appid']])
//            ->andFilterWhere(['<>', 'businessId', $businessId])
//            ->one();
//        $db = Db::connect('db_config1')->table('tenant');
//        $isAppid = $db->where(['appId'=>$result['authorization_info']['authorizer_appid']])->where('id','<>',$businessId)->find();
        $modelTenant = new Tenant();
        $isAppid = $modelTenant->where(['appId'=>$result['authorization_info']['authorizer_appid']])->where('id','<>',$businessId)->find();
        if (!empty($isAppid)) {
            $data = ['code' => 'error', 'msg' => '该微信小程序已经绑定过其他店铺，无法完成授权！'];
        }

        if ($data['code'] == 'success') {
            $isupdate = false;

            $businessMiniProgramModel = $modelTenant->where(['id'=>$businessId,])->find();
            //echo Tenant::getLastSql();exit;

//            //默认获取行业第一个模板
//            $businessInfo = Business::findOne(['businessId' => $businessId]);
//            $miniProgramTemplate = MiniProgramTemplate::find()->where(['industryId' => $businessInfo->industryId, 'status' => 10])->orderBy('id asc')->one();
            //$miniProgramTemplate = Miniprogramtemplate::
            //微信小程序更新字段

            $modedata = [
                //'templateId' => $miniProgramTemplate->id ?? '',
                'appId' => $result['authorization_info']['authorizer_appid'],
                'authorizerAccessToken' => $result['authorization_info']['authorizer_access_token'],
                'authorizerAccessTokenExpires' => date('Y-m-d H:i:s', $expiresTime),
                'authorizerRefreshToken' => $result['authorization_info']['authorizer_refresh_token'],
                'authTime' => time(),

            ];

            if (empty($businessMiniProgramModel)) {
                $modedata['id'] = $businessId;
                $modedata['wxStatus'] = 10;

            } else {
                if (!empty($businessMiniProgramModel->appId) && $businessMiniProgramModel->appId != $result['authorization_info']['authorizer_appid']) {
                    $data = ['code' => 'error', 'msg' => '当前店铺已绑定的微信小程序和您授权的微信小程序不同，无法完成授权！'];
                }else{
                    $modedata['wxStatus'] = 10;
                    $isupdate = true;
                }
            }

            if ($data['code'] == 'success') {
                if($isupdate){
                    $modelTenant->save($modedata,['id'=>$businessId]);
                }else{
                    $modelTenant->data($modedata);
                    $modelTenant->save();
                }
                //新商户自动提交审核
                //$MiniProgram = new MiniProgram();
                //$MiniProgram->newtemplateId();

            }
        }
        $this->assign('data',$data);

        return $this->fetch('authcodecallback');
    }

    /**
     * 解密
     * @param $xmlData
     * @return array|\SimpleXMLElement
     * @author fei <xliang.fei@gmail.com>
     */
    public static function decryptMsg($xmlData)
    {
        $encodingAesKey = config('miniprogram.MiaoDaoOpenEncodingAesKey');
        $token = config('miniprogram.MiaoDaoOpenToken');
        $appId = config('miniprogram.MiaoDaoOpenAppID');

        $get['timeStamp'] = !empty($_GET['timestamp']) ? $_GET['timestamp'] : '';
        $get['nonce'] = !empty($_GET['nonce']) ? $_GET['nonce'] : '';
        $get['msg_sign'] = !empty($_GET['msg_signature']) ? $_GET['msg_signature'] : '';

        $pc = new  WXBizMsgCrypt($token, $encodingAesKey, $appId);
        $encrypt = $xmlData->Encrypt;
        $format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>";
        $from_xml = sprintf($format, $encrypt);
        $data['msg'] = '';
        $data['errCode'] = $pc->decryptMsg($get['msg_sign'], $get['timeStamp'], $get['nonce'], $from_xml, $data['msg']);

        if ($data['errCode'] == 0) {
            $data['decryptMsg'] = simplexml_load_string($data['msg'], 'SimpleXMLElement', LIBXML_NOCDATA);
        }

        return $data;
    }

    /**
     * 记录Ticket推送数据
     * @param $xmlData  array   请求数据
     * @param $decryptMsg  array   请求数据
     * @param $msg  string  备注信息
     * @author fei <xliang.fei@gmail.com>
     */
    public static function saveMiniProgramTicketLog($xmlData, $decryptMsg, $msg = '')
    {
        file_put_contents(config('path.ticket_log_path'), '发起时间：' . date('Y-m-d H:i:s') . '  ' . $msg . ' 解密数据：' . json_encode($decryptMsg) . ' 请求数据：' . json_encode($xmlData) . PHP_EOL);
    }

    /**
     * 记录事件推送日志
     * @param $appId  string  请求地址
     * @param $request  array   请求数据
     * @param $msg  string  备注信息
     * @author fei <xliang.fei@gmail.com>
     */
    public static function saveMiniProgramEventLog($appId, $request, $msg = '')
    {
        file_put_contents(config('path.EventLog'), '发起时间：' . date('Y-m-d H:i:s') . ' appId：' . $appId . '  ' . $msg . ' 请求数据：' . json_encode($request) . PHP_EOL);
    }

    /**
     * 使用授权码换取公众号的授权信息(自动化测试的专用测试小程序)
     * @param $authorizationCode
     * @return bool|mixed
     * @author fei <xliang.fei@gmail.com>
     */
    private static function _wechatComponentApiQueryAuth($authorizationCode)
    {
        $access_token = MiniProgramHelp::getCompomentAccessToken();           //接口调用凭据
        $url = 'https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=' . $access_token;
        $postData['component_appid'] = config('miniprogram.MiaoDaoOpenAppID');
        $postData['authorization_code'] = $authorizationCode;

        $result = json_decode(BaseHelper::curlPost($url, json_encode($postData, JSON_UNESCAPED_UNICODE)), true);

        //记录日志
        MiniProgramHelp::saveMiniProgramLog($url, $postData, $result, '使用授权码换取公众号的授权信息');


        return $result;
    }

    /**
     * 客服接口-发消息(自动化测试的专用测试小程序)
     * @param $toUser
     * @param $authorizerAccessToken
     * @param $authorizationCode
     * @return mixed
     * @author fei <xliang.fei@gmail.com>
     */
    private static function _wechatSendMsg($toUser, $authorizerAccessToken, $authorizationCode)
    {
        $url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' . $authorizerAccessToken;

        $postData['touser'] = $toUser;
        $postData['msgtype'] = "text";
        $postData['text'] = [
            "content" => $authorizationCode . '_from_api'
        ];

        $result = json_decode(BaseHelper::curlPost($url, json_encode($postData, JSON_UNESCAPED_UNICODE)), true);

        //记录日志
        MiniProgramHelp::saveMiniProgramLog($url, $postData, $result, '客服接口-发消息');

        return $result;
    }
}